package com.xrui.util;

import com.xrui.exception.InvalidNameException;
import org.apache.hadoop.hbase.TableName;

import java.util.regex.Pattern;

/**
 * A utility class for validating layout names
 * (including table names, family names, and column names)
 */

public final class NameValidator {
    /**
     * Regular expression that defines a valid instance name.
     */
    public static final Pattern VALID_INSTANCE_PATTERN = Pattern.compile("[a-zA-Z0-9_]+");
    /**
     * Regular expression that defines a valid layout name (family, qualifier, table, etc).
     */
    public static final Pattern VALID_LAYOUT_NAME_PATTERN =
        Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*");
    /**
     * Regular expression that defines a valid table name.
     */
    public static final Pattern VALID_TABLE_NAME_PATTERN =
        Pattern.compile(TableName.VALID_USER_TABLE_REGEX);
    /**
     * Regular expression that defines a valid alias for a layout name.
     */
    public static final Pattern VALID_ALIAS_PATTERN =
        Pattern.compile("[a-zA-Z0-9_-]+");

    /**
     * Unused private constructor since this is a utility class.
     */
    private NameValidator() {
    }

    /**
     * @param name the name to check.
     * @return true if name is a valid name for a family or column name, and false otherwise.
     */
    public static boolean isValidLayoutName(CharSequence name) {
        return VALID_LAYOUT_NAME_PATTERN.matcher(name).matches();
    }

    /**
     * @param name the table name to check.
     * @return true if name is a valid name for a table and false otherwise.
     */
    public static boolean isValidTableName(CharSequence name) {
        return VALID_TABLE_NAME_PATTERN.matcher(name).matches();
    }

    /**
     * Determines whether a string is a valid layout name,
     * including table names, locality group names, family names, and column names.
     *
     * @param name The string to validate as a layout name.
     * @throws InvalidNameException If the name is invalid.
     */
    public static void validateLayoutName(CharSequence name) {
        if (!isValidLayoutName(name)) {
            throw new InvalidNameException("Invalid layout name: " + name);
        }
    }

    /**
     * @param name the name to check.
     * @return true if name is a valid alias for a table, locality group, family,
     * or column name, and false otherwise.
     */
    public static boolean isValidAlias(CharSequence name) {
        return VALID_ALIAS_PATTERN.matcher(name).matches();
    }

    /**
     * Validates characters that may be used in an alias for a qualifier, family, or
     * locality group. This is a superset of valid characters for a layout name.
     *
     * @param name The string to validate as a layout name alias.
     * @throws InvalidNameException If the name is invalid.
     */
    public static void validateAlias(CharSequence name) {
        if (!isValidAlias(name)) {
            throw new InvalidNameException("Invalid alias: " + name);
        }
    }

    /**
     * @param name the name to check.
     * @return true if name is a valid name for a  instance and false otherwise.
     */
    public static boolean isValidName(CharSequence name) {
        return VALID_INSTANCE_PATTERN.matcher(name).matches();
    }

    /**
     * Determines whether a string is a valid  instance name.
     *
     * @param name The string to validate as a  instance name.
     * @throws InvalidNameException If the name is invalid.
     */
    public static void validateName(CharSequence name) {
        if (!isValidName(name)) {
            throw new InvalidNameException("Invalid instance name: " + name);
        }
    }
}
